import { Injectable } from '@nestjs/common';
import { 
  ApiProvider, 
  TargetProvider, 
  GenericRequest, 
  GenericResponse,
  GenericMessage,
  GenericContentBlock,
  TokenManager
} from '../interfaces/api-adapter.interface';
import { BaseAdapter } from './base.adapter';
import { TokenManagerService } from '../services/token-manager.service';
import { CreateMessageDto, MessageResponseDto } from '../dto/messages.dto';

/**
 * Anthropic API 到 Copilot API 的适配器
 * 实现具体的格式转换逻辑
 */
@Injectable()
export class AnthropicCopilotAdapter extends BaseAdapter {
  constructor(private readonly tokenManager: TokenManagerService) {
    super(ApiProvider.ANTHROPIC, TargetProvider.COPILOT);
  }

  /**
   * 将 Anthropic 请求转换为通用格式
   */
  async convertToGeneric(anthropicRequest: CreateMessageDto): Promise<GenericRequest> {
    this.logConversion('Anthropic', 'Generic', { model: anthropicRequest.model });

    const genericMessages: GenericMessage[] = [];

    // 处理系统消息
    if (anthropicRequest.system) {
      const systemContent = typeof anthropicRequest.system === 'string' 
        ? anthropicRequest.system 
        : this.extractTextContent(anthropicRequest.system);
      
      if (systemContent) {
        genericMessages.push({
          role: 'system',
          content: systemContent
        });
      }
    }

    // 转换用户和助手消息
    anthropicRequest.messages.forEach(message => {
      const genericContent = this.convertAnthropicContentToGeneric(message.content);
      genericMessages.push({
        role: message.role as 'user' | 'assistant',
        content: genericContent
      });
    });

    const genericRequest: GenericRequest = {
      model: anthropicRequest.model,
      messages: genericMessages,
      max_tokens: anthropicRequest.max_tokens,
      temperature: anthropicRequest.temperature,
      top_p: anthropicRequest.top_p,
      stream: anthropicRequest.stream,
      metadata: {
        originalProvider: ApiProvider.ANTHROPIC,
        thinking: anthropicRequest.thinking
      }
    };

    // 处理工具
    if (anthropicRequest.tools && anthropicRequest.tools.length > 0) {
      genericRequest.tools = anthropicRequest.tools.map(tool => ({
        name: tool.name,
        description: tool.description,
        input_schema: tool.input_schema
      }));
    }

    return genericRequest;
  }

  /**
   * 将通用格式转换为 Copilot 请求格式
   */
  async convertFromGeneric(genericRequest: GenericRequest): Promise<any> {
    this.logConversion('Generic', 'Copilot', { model: genericRequest.model });

    const copilotMessages = genericRequest.messages.map(msg => ({
      role: msg.role,
      content: typeof msg.content === 'string' ? msg.content : this.extractTextContent(msg.content)
    }));

    const copilotRequest: any = {
      messages: copilotMessages,
      model: genericRequest.model,
      temperature: genericRequest.temperature || 0,
      top_p: genericRequest.top_p || 1,
      n: 1,
      max_tokens: genericRequest.max_tokens,
      stream: genericRequest.stream || true
    };

    // 处理工具
    if (genericRequest.tools && genericRequest.tools.length > 0) {
      copilotRequest.tools = genericRequest.tools.map(tool => ({
        type: 'function',
        function: {
          name: tool.name,
          description: tool.description,
          parameters: tool.input_schema
        }
      }));
    }

    // 处理思考模式
    if (genericRequest.metadata?.thinking?.enabled) {
      const systemMessage = copilotRequest.messages.find((m: any) => m.role === 'system');
      if (systemMessage) {
        systemMessage.content += '\n\nPlease think step by step before responding.';
      }
    }

    return copilotRequest;
  }

  /**
   * 解析 Copilot 响应为通用格式
   */
  async parseTargetResponse(copilotResponse: any, originalRequest?: any): Promise<GenericResponse> {
    this.logConversion('Copilot', 'Generic', { id: copilotResponse.id });

    if (!copilotResponse.choices || copilotResponse.choices.length === 0) {
      throw new Error('No choices in Copilot response');
    }

    const choice = copilotResponse.choices[0];
    const content: GenericContentBlock[] = [];

    // 处理普通文本内容
    if (choice.message.content) {
      content.push({
        type: 'text',
        text: choice.message.content
      });
    }

    // 处理工具调用
    if (choice.message.tool_calls) {
      choice.message.tool_calls.forEach((toolCall: any) => {
        content.push({
          type: 'tool_use',
          name: toolCall.function.name,
          input: JSON.parse(toolCall.function.arguments),
          tool_use_id: toolCall.id
        });
      });
    }

    return {
      id: copilotResponse.id,
      model: copilotResponse.model,
      content,
      stop_reason: this.mapStopReason(choice.finish_reason),
      usage: {
        input_tokens: copilotResponse.usage?.prompt_tokens || 0,
        output_tokens: copilotResponse.usage?.completion_tokens || 0,
        total_tokens: copilotResponse.usage?.total_tokens || 0
      },
      metadata: {
        originalTarget: TargetProvider.COPILOT,
        copilotModel: copilotResponse.model
      }
    };
  }

  /**
   * 将通用响应转换为 Anthropic 格式
   */
  async convertToSourceResponse(genericResponse: GenericResponse, originalRequest?: any): Promise<MessageResponseDto> {
    this.logConversion('Generic', 'Anthropic', { id: genericResponse.id });

    const anthropicContent = genericResponse.content.map(block => {
      switch (block.type) {
        case 'text':
          return {
            type: 'text' as const,
            text: block.text || ''
          };
        case 'tool_use':
          return {
            type: 'tool_use' as const,
            name: block.name || '',
            input: block.input || {},
            tool_use_id: block.tool_use_id || this.generateRequestId()
          };
        default:
          return {
            type: 'text' as const,
            text: String(block.text || '')
          };
      }
    });

    return {
      id: genericResponse.id,
      type: 'message',
      role: 'assistant',
      content: anthropicContent,
      model: genericResponse.model,
      stop_reason: genericResponse.stop_reason as any,
      stop_sequence: null,
      usage: {
        input_tokens: genericResponse.usage.input_tokens,
        output_tokens: genericResponse.usage.output_tokens,
        cache_creation_input_tokens: 0,
        cache_read_input_tokens: 0
      }
    };
  }

  /**
   * 获取请求头部
   */
  async getRequestHeaders(config: any): Promise<Record<string, string>> {
    const validToken = await this.tokenManager.getValidToken();
    
    return {
      'authorization': `Bearer ${validToken}`,
      'content-type': 'application/json',
      'copilot-integration-id': config.integrationId || 'jetbrains-chat',
      'copilot-language-server-version': config.lspVersion || '1.348.0',
      'editor-plugin-version': config.pluginVersion || 'copilot-intellij/1.5.52-241',
      'editor-version': config.editorVersion || 'JetBrains-IU/241.14494.240',
      'openai-intent': 'conversation-panel',
      'openai-organization': 'github-copilot',
      'x-github-api-version': '2025-05-01',
      'x-initiator': 'user',
      'x-interaction-type': 'conversation-panel',
      'vscode-machineid': config.machineId || '94d35625a61fd8f9fa14b64f9bf5c1cafe88359acc2dfa71fc527c04ec688653',
      'vscode-sessionid': config.sessionId || '0f8362b0-6939-4bc4-b1c5-0023da37a1461754191375398',
      'user-agent': config.userAgent || 'GithubCopilot/1.348.0',
      'x-request-id': this.generateRequestId()
    };
  }

  /**
   * 获取目标端点
   */
  getTargetEndpoint(operation: string): string {
    return `/chat/completions`;
  }

  /**
   * 获取 Token 管理器
   */
  getTokenManager(): TokenManager {
    return this.tokenManager;
  }

  /**
   * 获取必需字段
   */
  protected getRequiredFields(): string[] {
    return ['model', 'messages'];
  }

  /**
   * 转换 Anthropic 内容块为通用格式
   */
  private convertAnthropicContentToGeneric(content: any): string | GenericContentBlock[] {
    if (typeof content === 'string') {
      return content;
    }

    if (Array.isArray(content)) {
      return content.map(block => {
        switch (block.type) {
          case 'text':
            return {
              type: 'text' as const,
              text: block.text
            };
          case 'tool_use':
            return {
              type: 'tool_use' as const,
              name: block.name,
              input: block.input,
              tool_use_id: block.tool_use_id
            };
          case 'tool_result':
            return {
              type: 'tool_result' as const,
              content: block.content,
              tool_use_id: block.tool_use_id
            };
          default:
            return {
              type: 'text' as const,
              text: String(block.text || '')
            };
        }
      });
    }

    return String(content);
  }

}